From 13d3a566ac7e866e81f3941e6402a4fa3628dd88 Mon Sep 17 00:00:00 2001 From: "cl349@freefall.cl.cam.ac.uk" Date: Thu, 28 Oct 2004 23:24:39 +0000 Subject: [PATCH] bitkeeper revision 1.1159.1.301 (41817fb7qo-OpONURmWllN-zVtSETA) Add checks to prevent unsafe sharing of block devices between domains. Can be overridden by adding ! to the devices mode. --- tools/python/xen/xend/server/SrvDaemon.py | 4 +- tools/python/xen/xend/server/blkif.py | 48 ++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 42b8a8ca39..cc7da8ee43 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -649,7 +649,9 @@ class Daemon: Returns controller """ - return self.blkifCF.getController(dom) + blkif = self.blkifCF.getController(dom) + blkif.daemon = self + return blkif def blkifs(self): return [ x.sxpr() for x in self.blkifCF.getControllers() ] diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index 79998299cb..5a013b1904 100755 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -16,16 +16,45 @@ import channel import controller from messages import * +def expand_dev_name(name): + if re.match( '^/dev/', name ): + return name + else: + return '/dev/' + name + +def check_mounted(self, name): + mode = None + name = expand_dev_name(name) + lines = os.popen('mount 2>/dev/null').readlines() + exp = re.compile('^' + name + '.*[\(,]r(?P[ow])[,\)]') + for line in lines: + pm = exp.match(line) + if not pm: continue + mode = pm.group('mode') + break + if mode is 'w': + return mode + if mode is 'o': + mode = 'r' + blkifs = self.ctrl.daemon.blkifs() + for blkif in blkifs: + if blkif[1][1] is self.ctrl.dom: + continue + for dev in self.ctrl.daemon.blkif_get(blkif[1][1]).getDevices(): + if dev.type == 'phy' and name == expand_dev_name(dev.params): + mode = dev.mode + if 'w' in mode: + return 'w' + if mode and 'r' in mode: + return 'r' + return None def blkdev_name_to_number(name): """Take the given textual block-device name (e.g., '/dev/sda1', 'hda') and return the device number used by the OS. """ - if re.match( '^/dev/', name ): - n = name - else: - n = '/dev/' + name - + n = expand_dev_name(name) + try: return os.stat(n).st_rdev except Exception, ex: @@ -283,6 +312,7 @@ class BlkDev(controller.SplitDev): self.device = None self.start_sector = None self.nr_sectors = None + self.ctrl = ctrl self.configure(config) def configure(self, config): @@ -322,6 +352,14 @@ class BlkDev(controller.SplitDev): Blkctl.block('unbind', self.type, self.node) def setNode(self, node): + mounted_mode = check_mounted(self, node) + if not '!' in self.mode and mounted_mode: + if mounted_mode is "w": + raise VmError("vbd: Segment %s is in writable use" % + self.uname) + elif 'w' in self.mode: + raise VmError("vbd: Segment %s is in read-only use" % + self.uname) segment = blkdev_segment(node) if not segment: raise VmError("vbd: Segment not found: uname=%s" % self.uname) -- 2.30.2